package com.cskaoyan.javase.exception.handle2.throws3;

/**
 * @description: throws关键字
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * > throws关键字表示在方法上抛出异常
 * - 在方法声明时使用，声明该方法可能抛出的异常类型
 * 语法:
 *
 * 方法名(形参列表) throws 异常列表{
 * }
 * 明确两点：
 * 1，throws关键字用在方法的声明中
 * 2，throws只是表示可能抛出异常，到底抛不抛出要看代码的执行结果
 *
 * throws表示的抛出的可能性，那么它只要指定抛出的异常的类型即可，不需要明确抛出一个对象
 *
 * 注意事项:
 *
 * - 运行时异常会自动向上抛出，不用我们手动throws
 *   - 我们只需要手动throws编译时异常
 * - 如果方法抛出一个编译时异常，可以在语法层面，强制要求方法调用者处理该异常
 *
 * - 异常列表可以是多个异常类，但是注意用逗号隔开
 * - 列表中出现的异常如果有父子关系，那么编译器只会强制要求处理父类
 *   - 所以尽量抛出同级别的异常
 *
 * 细节：如果一个程序抛出Exception，它会被作为编译时异常处理
 *
 * throws的作用：
 *  在方法声明中声明可能抛出的异常，如果这个异常是编译时异常，那么就强制方法的调用者去处理他
 *  告诉方法的调用者 我可能有问题，所以你要提前做好准备，要准备应对异常情况
 */
public class Demo {
    public static void main(String[] args)  {
        //正常情况下，对于一个编译时异常，抛给jvm 显然是不合适的 因为这样会程序终止报错
        //正常的情况下，应该捕获并处理这个编译时异常 ALT+回车
        //try {
        //    test();
        //} catch (CloneNotSupportedException e) {
        //    e.printStackTrace();
        //}
        //System.out.println("try catch 之后");
        try {
            test();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("对异常情况做处理");
        }
    }

    public static void test() throws Exception {
        /*
        运行时异常 不需要手动 throws
        String s = null;
        System.out.println(s.length());*/

        //编译时异常
        Student s = new Student();
        //方法的声明中如果写了抛出编译时异常，那么在方法的调用处就必须显式的处理
        s.clone();
    }
}
class Student{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
